#ifndef __XCAN_H__
#define __XCAN_H__
#include <linux/bitfield.h>
#include "drv_pcie.h"
#include "drv_pcie_irq.h"
#include "drv_cdev.h"
#include "drv_xcan_dev.h"

#undef XCAN_BERR_REPORT

// 中断寄存器定义
#define IRQ_MSI_MASK_REG        0x5C

// CANFD 读写寄存器定义
#define CANFD_TEST_REG          0x00
#define CANFD_VERSION_REG       0x04
#define CANFD_WR_ADDR_REG       0x0C
#define CANFD_WR_DATA_REG       0x10
#define CANFD_RD_ADDR_REG       0x14
#define CANFD_RD_DATA_REG       0x18
#define CANFD_MSI_MASK_REG      0x60

#define CAN_WR_ADDR_REG         0x1C
#define CAN_WR_DATA_REG         0x20
#define CAN_RD_ADDR_REG         0x24
#define CAN_RD_DATA_REG         0x28

// CANFD 寄存器位偏移定义
#define CANFD_DEV_ID_SHIFT     16

#define XCAN_FRAME_ID_OFFSET(frame_base)    ((frame_base) + 0x00)
#define XCAN_FRAME_DLC_OFFSET(frame_base)   ((frame_base) + 0x04)
#define XCAN_FRAME_DW1_OFFSET(frame_base)   ((frame_base) + 0x08)
#define XCAN_FRAME_DW2_OFFSET(frame_base)   ((frame_base) + 0x0C)
#define XCANFD_FRAME_DW_OFFSET(frame_base)  ((frame_base) + 0x08)

#define XCAN_CANFD_FRAME_SIZE           0x48
#define XCAN_TXMSG_FRAME_OFFSET(n)      (XCAN_TXMSG_BASE_OFFSET + \
                                        XCAN_CANFD_FRAME_SIZE * (n))
#define XCAN_RXMSG_FRAME_OFFSET(n)      (XCAN_RXMSG_BASE_OFFSET + \
                                        XCAN_CANFD_FRAME_SIZE * (n))
#define XCAN_RXMSG_2_FRAME_OFFSET(n)    (XCAN_RXMSG_2_BASE_OFFSET + \
                                        XCAN_CANFD_FRAME_SIZE * (n))

/* the single TX mailbox used by this driver on CAN FD HW */
#define XCAN_TX_MAILBOX_IDX     0

/* CAN register bit masks - XCAN_<REG>_<BIT>_MASK */
#define XCAN_SRR_CEN_MASK       0x00000002      /* CAN enable */
#define XCAN_SRR_RESET_MASK     0x00000001      /* Soft Reset the CAN core */
#define XCAN_MSR_LBACK_MASK     0x00000002      /* Loop back mode select */
#define XCAN_MSR_SLEEP_MASK     0x00000001      /* Sleep mode select */
#define XCAN_BRPR_BRP_MASK      0x000000FF      /* Baud rate prescaler */
#define XCAN_BTR_SJW_MASK       0x00000180      /* Synchronous jump width */
#define XCAN_BTR_TS2_MASK       0x00000070      /* Time segment 2 */
#define XCAN_BTR_TS1_MASK       0x0000000F      /* Time segment 1 */
#define XCAN_BTR_SJW_MASK_CANFD 0x000F0000      /* Synchronous jump width */
#define XCAN_BTR_TS2_MASK_CANFD 0x00000F00      /* Time segment 2 */
#define XCAN_BTR_TS1_MASK_CANFD 0x0000003F      /* Time segment 1 */
#define XCAN_ECR_REC_MASK       0x0000FF00      /* Receive error counter */
#define XCAN_ECR_TEC_MASK       0x000000FF      /* Transmit error counter */
#define XCAN_ESR_ACKER_MASK     0x00000010      /* ACK error */
#define XCAN_ESR_BERR_MASK      0x00000008      /* Bit error */
#define XCAN_ESR_STER_MASK      0x00000004      /* Stuff error */
#define XCAN_ESR_FMER_MASK      0x00000002      /* Form error */
#define XCAN_ESR_CRCER_MASK     0x00000001      /* CRC error */
#define XCAN_SR_TXFLL_MASK      0x00000400      /* TX FIFO is full */
#define XCAN_SR_ESTAT_MASK      0x00000180      /* Error status */
#define XCAN_SR_ERRWRN_MASK     0x00000040      /* Error warning */
#define XCAN_SR_NORMAL_MASK     0x00000008      /* Normal mode */
#define XCAN_SR_LBACK_MASK      0x00000002      /* Loop back mode */
#define XCAN_SR_CONFIG_MASK     0x00000001      /* Configuration mode */
#define XCAN_IXR_RXMNF_MASK     0x00020000      /* RX match not finished */
#define XCAN_IXR_TXFEMP_MASK    0x00004000      /* TX FIFO Empty */
#define XCAN_IXR_WKUP_MASK      0x00000800      /* Wake up interrupt */
#define XCAN_IXR_SLP_MASK       0x00000400      /* Sleep interrupt */
#define XCAN_IXR_BSOFF_MASK     0x00000200      /* Bus off interrupt */
#define XCAN_IXR_ERROR_MASK     0x00000100      /* Error interrupt */
#define XCAN_IXR_RXNEMP_MASK    0x00000080      /* RX FIFO NotEmpty intr */
#define XCAN_IXR_RXOFLW_MASK    0x00000040      /* RX FIFO Overflow intr */
#define XCAN_IXR_RXOK_MASK      0x00000010      /* Message received intr */
#define XCAN_IXR_TXFLL_MASK     0x00000004      /* Tx FIFO Full intr */
#define XCAN_IXR_TXOK_MASK      0x00000002      /* TX successful intr */
#define XCAN_IXR_ARBLST_MASK    0x00000001      /* Arbitration lost intr */
#define XCAN_IDR_ID1_MASK       0xFFE00000      /* Standard msg identifier */
#define XCAN_IDR_SRR_MASK       0x00100000      /* Substitute remote TXreq */
#define XCAN_IDR_IDE_MASK       0x00080000      /* Identifier extension */
#define XCAN_IDR_ID2_MASK       0x0007FFFE      /* Extended message ident */
#define XCAN_IDR_RTR_MASK       0x00000001      /* Remote TX request */
#define XCAN_DLCR_DLC_MASK      0xF0000000      /* Data length code */
#define XCAN_FSR_FL_MASK        0x00003F00      /* RX Fill Level */
#define XCAN_2_FSR_FL_MASK      0x00007F00      /* RX Fill Level */
#define XCAN_FSR_IRI_MASK       0x00000080      /* RX Increment Read Index */
#define XCAN_FSR_RI_MASK        0x0000001F      /* RX Read Index */
#define XCAN_2_FSR_RI_MASK      0x0000003F      /* RX Read Index */
#define XCAN_DLCR_EDL_MASK      0x08000000      /* EDL Mask in DLC */
#define XCAN_DLCR_BRS_MASK      0x04000000      /* BRS Mask in DLC */

#define XCAN_SR_ERRACT_MASK     0x00000080      /* Error active */
#define XCAN_SR_ERRPSV_MASK     0x00000180      /* Error passive */
#define XCAN_SR_BSOFF_MASK      0x00000100      /* busoff */
/* only pango use */
#define XCAN_FIFO_CR_RFC_MASK   0x00000010      /* RX_FIFO 信息读完成指示 */
#define XCAN_FIFO_CR_TFC_MASK   0x00000001      /* TX_FIFO 信息配置完成指示 */

/* CAN register bit shift - XCAN_<REG>_<BIT>_SHIFT */
#define XCAN_BTR_SJW_SHIFT          7           /* Synchronous jump width */
#define XCAN_BTR_TS2_SHIFT          4           /* Time segment 2 */
#define XCAN_BTR_SJW_SHIFT_CANFD    16          /* Synchronous jump width */
#define XCAN_BTR_TS2_SHIFT_CANFD    8           /* Time segment 2 */
#define XCAN_IDR_ID1_SHIFT          21          /* Standard Messg Identifier */
#define XCAN_IDR_ID2_SHIFT          1           /* Extended Message Identifier */
#define XCAN_DLCR_DLC_SHIFT         28          /* Data length code */
#define XCAN_ESR_REC_SHIFT          8           /* Rx Error Count */

/* CAN frame length constants */
#define XCAN_FRAME_MAX_DATA_LEN 8
#define XCANFD_DW_BYTES         4
#define XCAN_TIMEOUT            (1 * HZ)

/* TX-FIFO-empty interrupt available */
#define XCAN_FLAG_TXFEMP        0x0001
/* RX Match Not Finished interrupt available */
#define XCAN_FLAG_RXMNF         0x0002
/* Extended acceptance filters with control at 0xE0 */
#define XCAN_FLAG_EXT_FILTERS   0x0004
/* TX mailboxes instead of TX FIFO */
#define XCAN_FLAG_TX_MAILBOXES  0x0008
/* RX FIFO with each buffer in separate registers at 0x1100
 * instead of the regular FIFO at 0x50
 */
#define XCAN_FLAG_RX_FIFO_MULTI 0x0010
#define XCAN_FLAG_CANFD_2       0x0020

#define XCAN_RX_FIFO_DEPTH      64      /* rx-fifo-depth */

// #define CANFD_DRV_NAME      "pcie_canfd"
// #define CANFD_DEV_NUM       3
// #define CAN_DRV_NAME        "pcie_can"
// #define CAN_DEV_NUM         6

// #define DEV_NUM             (9 + 1)
#ifndef PCI_STD_NUM_BARS
#define PCI_STD_NUM_BARS    6       /* Number of standard BARs */
#endif
#define PCI_BAR0            0
#define PCI_BAR1            1

struct canfd_msg_t
{
    unsigned char fmt;          /* frame format, 0: Std; 1: Ext */
    unsigned char rtr;          /* frame type, 0: data frames; 1: long-range frames */
    unsigned long id;           /* can id, CAN: 0x00-0x7FF; CANFD: 0x00-0x1FFFFFFF */
    unsigned char dlc;          /* data length, CAN: 0~8; CANFD: 0~64 */
    unsigned char flg;          /* canfd flag, CAN: 0; CANFD: 1 */
    unsigned char data[64];     /* payload (0-64 bytes) */
};

#define CIRC_BUF_SIZE   4096    /* 缓冲区总大小，必须是 2 的幂次方 */
/* 环形缓冲区 */
struct circ_buf_t {
    size_t size;        /* 缓冲区总大小，必须是 2 的幂次方 */
    size_t head;        /* 写索引 */
    size_t tail;        /* 读索引 */
    struct canfd_msg_t msg[CIRC_BUF_SIZE];
};

#pragma pack(push, 4)
union xcan_sr_u {
    u32 val;                    /* 寄存器值 */
    struct {
        u32 config  : 1;        /* 配置模式指示器(bit[0]) */
        u32 lback   : 1;        /* 环回模式(bit[1]) */
        u32 sleep   : 1;        /* 睡眠模式(bit[2]) */
        u32 normal  : 1;        /* 正常模式(bit[3]) */
        u32 bidle   : 1;        /* 总线空闲(bit[4]) */
        u32 bbsy    : 1;        /* 总线忙(bit[5]) */
        u32 errwrn  : 1;        /* 错误警告(bit[6]) */
        u32 estat   : 2;        /* 错误状态(bit[8:7]) */
        u32 txbfll  : 1;        /* 高优先级发送 Buffer 满(only CAN bit[9]) */
        u32 txfll   : 1;        /* 发送 FIFO 满(only CAN bit[10]) */
        u32 res     : 21;       /* 保留位(bit[31:11]) */
    } bits;
};

union xcan_ecr_u {
    u32 val;                    /* 寄存器值 */
    struct {
        u32 tec     : 8;        /* 发送错误计数(bit[7:0]) */
        u32 rec     : 8;        /* 接收错误计数(bit[15:8]) */
        u32 res     : 16;       /* 保留位(bit[31:16]) */
    } bits;
};

#pragma pack(pop)

struct xcan_reg_t {
    u32 srr;                    /* 软件复位寄存器(0x00) */
    u32 msr;                    /* 模式选择寄存器(0x04) */
    u32 brpr;                   /* 仲裁阶段(标称)波特率预分频器寄存器(0x08) */
    u32 btr;                    /* 仲裁阶段(标称)位定时寄存器(0x0C) */
    union xcan_ecr_u ecr;       /* 错误计数寄存器(0x10) */
    u32 esr;                    /* 错误状态寄存器(0x14) */
    union xcan_sr_u sr;         /* 状态寄存器(0x18) */
    u32 isr;                    /* 中断状态寄存器(0x1C) */
    u32 ier;                    /* 中断使能寄存器(0x20) */
    u32 icr;                    /* 中断清零寄存器(0x24) */
    u32 data_brpr;              /* 数据相位波特率预分频器寄存器(0x88) */
    u32 data_btr;               /* 数据相位位定时寄存器(0x8C) */
};

struct xcan_filter_t {
    u32 mask;
    u32 id;
};
enum xcan_ip_type {
	XAXI_CAN = 0,
	XZYNQ_CANPS,
	XAXI_CANFD,
	XAXI_CANFD_2_0,
};
struct xcan_devtype_data {
	enum xcan_ip_type cantype;
	unsigned int flags;
	const struct can_bittiming_const *bittiming_const;
	const char *bus_clk_name;
	unsigned int btr_ts2_shift;
	unsigned int btr_sjw_shift;
};

/* CAN registers set */
enum xcan_core_reg {
    XCAN_SRR_OFFSET         = 0x00,     /* Software reset */
    XCAN_MSR_OFFSET         = 0x04,     /* Mode select */
    XCAN_BRPR_OFFSET        = 0x08,     /* Baud rate prescaler */
    XCAN_BTR_OFFSET         = 0x0C,     /* Bit timing */
    XCAN_ECR_OFFSET         = 0x10,     /* Error counter */
    XCAN_ESR_OFFSET         = 0x14,     /* Error status */
    XCAN_SR_OFFSET          = 0x18,     /* Status */
    XCAN_ISR_OFFSET         = 0x1C,     /* Interrupt status */
    XCAN_IER_OFFSET         = 0x20,     /* Interrupt enable */
    XCAN_ICR_OFFSET         = 0x24,     /* Interrupt clear */
    /* only pango use*/
    XCAN_FIFO_CTRL_OFFSET   = 0x2C,     /* FIFO control */

    /* not on CAN FD cores */
    XCAN_TXFIFO_OFFSET  = 0x30,     /* TX FIFO base */
    XCAN_RXFIFO_OFFSET  = 0x50,     /* RX FIFO base */
    XCAN_AFR_OFFSET     = 0x60,     /* Acceptance Filter */
    XCAN_AFMR_1_OFFSET  = 0x64,     /* Acceptance Filter MASK */
    XCAN_AFIR_1_OFFSET  = 0x68,     /* Acceptance Filter ID */

    /* only on CAN FD cores */
    XCAN_F_BRPR_OFFSET          = 0x088,        /* Data Phase Baud Rate Prescalar */
    XCAN_F_BTR_OFFSET           = 0x08C,        /* Data Phase Bit Timing */
    XCAN_TRR_OFFSET             = 0x0090,       /* TX Buffer Ready Request */
    XCAN_AFR_EXT_OFFSET         = 0x00E0,       /* Acceptance Filter */
    XCAN_FSR_OFFSET             = 0x00E8,       /* RX FIFO Status */
    XCAN_TXMSG_BASE_OFFSET      = 0x0100,       /* TX Message Space */
    XCAN_RXMSG_BASE_OFFSET      = 0x1100,       /* RX Message Space */
    XCAN_RXMSG_2_BASE_OFFSET    = 0x2100,       /* RX Message Space */
    XCAN_AFR_2_MASK_OFFSET      = 0x0A00,       /* Acceptance Filter MASK */
    XCAN_AFR_2_ID_OFFSET        = 0x0A04,       /* Acceptance Filter ID */
};

/* 寄存器数据描述符 */
struct reg_data_t {
    u32 addr;
    u32 val;
};

struct xcan_sta_t {
    u8 config;          /* 配置模式指示器(bit[0]) */
    u8 lback;           /* 环回模式(bit[1]) */
    u8 sleep;           /* 睡眠模式(bit[2]) */
    u8 normal;          /* 正常模式(bit[3]) */
    u8 bidle;           /* 总线空闲(bit[4]) */
    u8 bbsy ;           /* 总线忙(bit[5]) */
    u8 errwrn;          /* 错误警告(bit[6]) */
    // u8 estat;           /* 错误状态(bit[8:7]) */
    u8 erract;          /* 错误活动状态(bit[8:7]->01) */
    u8 errpsv;          /* 错误被动状态(bit[8:7]->11) */
    u8 bsoff;           /* 总线关闭状态(bit[8:7]->10) */
    u8 txfll;           /* 发送 FIFO 满(only CAN bit[10]) */
};

struct xcan_ecnt_t {
    u8 tec;
    u8 rec;
};

/* IOCTL 命令定义 */
#define IOCTL_XCAN_MAGIC                    'P'                                                     /* 魔术字符，标识设备驱动 */
#define IOCTL_XCAN_READ_REG                 _IOR(IOCTL_XCAN_MAGIC, 10, struct reg_data_t)           /* 读寄存器 */
#define IOCTL_XCAN_WRITE_REG                _IOW(IOCTL_XCAN_MAGIC, 11, struct reg_data_t)           /* 写寄存器 */
#define IOCTL_XCAN_READ_MSG                 _IOW(IOCTL_XCAN_MAGIC, 12, struct canfd_msg_t)          /* 读取报文 */
#define IOCTL_XCAN_CLEAR_MSG                _IO(IOCTL_XCAN_MAGIC, 13)                               /* 清空报文 */
#define IOCTL_XCAN_SET_CTRLMODE             _IOW(IOCTL_XCAN_MAGIC, 14, u32)                         /* 读取报文 */
#define IOCTL_XCAN_GET_CTRLMODE             _IOR(IOCTL_XCAN_MAGIC, 15, u32)                         /* 读寄存器 */
#define IOCTL_XCAN_SET_BITTIMING            _IOW(IOCTL_XCAN_MAGIC, 16, struct can_bittiming)        /* 读取报文 */
#define IOCTL_XCAN_GET_BITTIMING            _IOR(IOCTL_XCAN_MAGIC, 17, struct can_bittiming)        /* 读寄存器 */
#define IOCTL_XCAN_SET_DATA_BITTIMING       _IOW(IOCTL_XCAN_MAGIC, 18, struct can_bittiming)        /* 读取报文 */
#define IOCTL_XCAN_GET_DATA_BITTIMING       _IOR(IOCTL_XCAN_MAGIC, 19, struct can_bittiming)        /* 读寄存器 */
#define IOCTL_XCAN_SET_FILTER               _IOW(IOCTL_XCAN_MAGIC, 20, struct xcan_filter_t)        /* 设置帧过滤 */
#define IOCTL_XCAN_SET_MODE                 _IOW(IOCTL_XCAN_MAGIC, 21, int)                         /* 设置模式 */
#define IOCTL_XCAN_GET_STA                  _IOR(IOCTL_XCAN_MAGIC, 22, struct xcan_sta_t)           /* 获取状态 */
#define IOCTL_XCAN_GET_ERR_CNT              _IOR(IOCTL_XCAN_MAGIC, 23, struct xcan_ecnt_t)          /* 获取错误计数 */

#define IOCTL_XCAN_GET_DRV_VERSION          _IOR(IOCTL_XCAN_MAGIC, 101, u32)                        /* 获取驱动版本号 */
#define IOCTL_XCAN_GET_FPGA_VERSION         _IOR(IOCTL_XCAN_MAGIC, 102, u32)                        /* 获取 FPGA 版本号 */

/**
 * struct xcan_dev_t - This definition define CAN driver instance
 * @can:			CAN private data structure.
 * @tx_lock:			Lock for synchronizing TX interrupt handling
 * @tx_head:			Tx CAN packets ready to send on the queue
 * @tx_tail:			Tx CAN packets successfully sended on the queue
 * @tx_max:			Maximum number packets the driver can send
 * @napi:			NAPI structure
 * @read_reg:			For reading data from CAN registers
 * @write_reg:			For writing data to CAN registers
 * @dev:			Network device data structure
 * @reg_base:			Ioremapped address to registers
 * @irq_flags:			For request_irq()
 * @bus_clk:			Pointer to struct clk
 * @can_clk:			Pointer to struct clk
 * @devtype:			Device type specific constants
 */
struct xcan_dev_t {      // CANFD数据结构
    void *parent;                       /* 父设备指针 */
    struct device *dev;                 /* 设备描述符 */
    struct mutex lock;                  /* 互斥锁 */
    char name[32];                      /* 设备名 */
    u8 index;                           /* 索引号 */

    struct work_struct work;
    struct xcan_device_stats stats;     /* 状态 */
    // int restart_ms;                     /* 延时重启设备 */
    // struct delayed_work restart_work;   /* 重启设备延时队列 */
    struct circ_buf_t rx_circ;          /* 接收环形缓冲区 */
    spinlock_t rx_splock;               /* 自旋锁保护缓冲区（中断安全） */
    wait_queue_head_t rx_wqh;           /* 接收等待队列 */
    struct circ_buf_t tx_circ;          /* 发送环形缓冲区 */
    spinlock_t tx_splock;               /* 自旋锁保护缓冲区（中断安全） */
    struct xcan_filter_t filter;        /* 帧过滤 */

    struct canfd_frame rx_frame;        // 接收帧
    struct canfd_frame tx_frame;        // 发送帧

    struct can_priv can;                // CAN 设备描述符
    spinlock_t tx_lock;                 /* Lock for synchronizing TX interrupt handling */
    wait_queue_head_t tx_wqh;           /* 发送等待队列 */
    unsigned int tx_head;
    unsigned int tx_tail;
    unsigned int tx_max;
    u32 (*read_ipcore)(struct xcan_dev_t *priv, enum xcan_core_reg reg);
    void (*write_ipcore)(struct xcan_dev_t *priv, enum xcan_core_reg reg, u32 val);
    
    void __iomem *reg_base;             // 寄存器空间映射（内核虚拟地址）
    int wr_addr_reg;
    int wr_data_reg;
    int rd_addr_reg;
    int rd_data_reg;
    struct xcan_devtype_data devtype;

    struct xcan_reg_t reg;              /* 寄存器 */
    struct xcan_sta_t sta;              /* 状态 */
    struct xcan_ecnt_t ecnt;            /* 错误计数 */
};

// 设备特定数据结构
struct xcan_ctrl_t {
    struct device *dev;                                                 /* 设备描述符 */
    struct mutex lock;                                                  /* 互斥锁 */
    char name[32];                                                      /* 设备名称 */
    int num;                                                            /* 设备数量 */

    struct pcie_dev_t *ppdev;                                           /* PCIe 设备指针 */
    u32 (*read_reg)(struct pcie_dev_t *ppdev, u32 reg);                 /* 读寄存器 */
    void (*write_reg)(struct pcie_dev_t *ppdev, u32 reg, u32 val);      /* 写寄存器 */
    u32 (*read_mem)(void __iomem *mem, u32 offset);                     /* 读内存 */
    void (*write_mem)(void __iomem *mem, u32 offset, u32 val);          /* 读内存 */
    struct cdev_ctrl_t cdev_ctrl;                                       /* 字符设备控制器 */
    struct pcie_irq_ctrl_t irq_ctrl;                                    /* 中断 */
    struct xcan_dev_t *xcan;                                            /* XCAN */

    u32 drv_ver;                                                        /* 驱动版本号 */
    u32 fpga_ver;                                                       /* FPGA 版本号 */
};

extern const struct xcan_devtype_data xcan_axi_data;
extern const struct xcan_devtype_data xcan_canfd2_data;

int xcan_do_set_mode(struct xcan_dev_t *priv, enum can_mode mode);
/* 初始化 XCAN 控制器 */
int init_xcan_ctrl(struct pcie_dev_t *pcie_dev, struct cdev_dev_t *cdev_dev, 
                   struct xcan_ctrl_t *pctrl, struct xcan_dev_t *xcan, 
                   const char *ctrl_name, u8 dev_num, const struct xcan_devtype_data *type);
/* 注销 XCAN 控制器 */
void exit_xcan_ctrl(struct xcan_ctrl_t *pctrl, u8 dev_num);

#endif /* __XCAN_H__ */
